package com.haixiaoke.saas.bill.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.haixiaoke.saas.bill.domain.ProprietorBill;
import com.haixiaoke.saas.bill.mapper.ProprietorBillMapper;
import com.haixiaoke.saas.bill.service.IProprietorBillService;
import com.haixiaoke.saas.common.constant.BillConstants;
import com.haixiaoke.saas.common.core.redis.RedisCache;
import com.haixiaoke.saas.common.enums.BillStateEnum;
import com.haixiaoke.saas.common.enums.HouseStateEnum;
import com.haixiaoke.saas.common.exception.ServiceException;
import com.haixiaoke.saas.common.utils.DateUtils;
import com.haixiaoke.saas.common.weChat.domain.ParseParam;
import com.haixiaoke.saas.house.domain.House;
import com.haixiaoke.saas.house.service.IHouseService;
import com.haixiaoke.saas.order.domain.WechatPayRecord;
import com.haixiaoke.saas.order.service.IWechatPayRecordService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;


/**
 * 业主账单Service业务层处理
 *
 * @author qixi
 * @date 2024-05-28
 */
@Service
@Slf4j
public class ProprietorBillServiceImpl implements IProprietorBillService {
    @Autowired
    private ProprietorBillMapper proprietorBillMapper;

    @Autowired
    private IHouseService houseService;
    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IWechatPayRecordService wechatPayRecordService;


    /**
     * 查询业主账单
     *
     * @param proprietorBillId 业主账单主键
     * @return 业主账单
     */
    @Override
    public ProprietorBill selectProprietorBillByProprietorBillId(String proprietorBillId) {
        return proprietorBillMapper.selectProprietorBillByProprietorBillId(proprietorBillId);
    }

    /**
     * 查询业主账单列表
     *
     * @param proprietorBill 业主账单
     * @return 业主账单
     */
    @Override
    public List<ProprietorBill> selectProprietorBillList(ProprietorBill proprietorBill) {
        return proprietorBillMapper.selectProprietorBillList(proprietorBill);
    }

    /**
     * 新增业主账单
     *
     * @param proprietorBill 业主账单
     * @return 结果
     */
    @Override
    public int insertProprietorBill(ProprietorBill proprietorBill) {
        proprietorBill.setCreateTime(DateUtils.getNowDate());
        return proprietorBillMapper.insertProprietorBill(proprietorBill);
    }

    /**
     * 修改业主账单
     *
     * @param proprietorBill 业主账单
     * @return 结果
     */
    @Override
    public int updateProprietorBill(ProprietorBill proprietorBill) {
        proprietorBill.setUpdateTime(DateUtils.getNowDate());
        return proprietorBillMapper.updateProprietorBill(proprietorBill);
    }

    /**
     * 批量删除业主账单
     *
     * @param proprietorBillIds 需要删除的业主账单主键
     * @return 结果
     */
    @Override
    public int deleteProprietorBillByProprietorBillIds(String[] proprietorBillIds) {
        return proprietorBillMapper.deleteProprietorBillByProprietorBillIds(proprietorBillIds);
    }

    /**
     * 删除业主账单信息
     *
     * @param proprietorBillId 业主账单主键
     * @return 结果
     */
    @Override
    public int deleteProprietorBillByProprietorBillId(String proprietorBillId) {
        return proprietorBillMapper.deleteProprietorBillByProprietorBillId(proprietorBillId);
    }

    @Override
    public ProprietorBill insertProprietorBillByHouse(String houseId) {


        // String houseId = proprietorBill.getHouseId();
        // if (StrUtil.isEmpty(houseId)) {
        //     throw new ServiceException("房源ID不能为空");
        // }

        House house = houseService.selectHouseById(houseId);
        if (house == null) {
            throw new ServiceException("房源不存在");
        }


        String cooperationType = house.getCooperationType();
        if (HouseStateEnum.COOPERATION_TYPE_AGENCY.getValue().equals(cooperationType)) {
            // 合作房源
            String chargeType = house.getChargeType();
            if (HouseStateEnum.CHARGE_TYPE_DISPOSABLE.getValue().equals(chargeType)) {
                // 一次性付款生成业主账单
                ProprietorBill proprietorBill = new ProprietorBill();
                String proprietorId = "PB" + System.currentTimeMillis() + RandomUtils.nextInt(10000, 100000);
                proprietorBill.setHouseId(houseId);
                proprietorBill.setProprietorBillId(proprietorId);
                proprietorBill.setBillType(ProprietorBill.BILL_TYPE_ONCE);
                proprietorBill.setCost(house.getFeeAmount());
                proprietorBill.setUserId(house.getProprietorUserId());
                proprietorBill.setUserName(house.getProprietorName());
                Date latestPaymentDate = house.getLatestPaymentDate();
                proprietorBill.setLatestPayTime(getLatestPayTime(latestPaymentDate));
                proprietorBill.setTenantId(house.getTenantId());
                // proprietorBill.setDeptId(house.getDeptId());
                proprietorBill.setCreateTime(DateUtils.getNowDate());
                proprietorBillMapper.insertProprietorBill(proprietorBill);
                return proprietorBill;
            }
        }
        return null;
    }

    private DateTime getLatestPayTime(Date checkInTime) {
        // endOfDay方法会将时间毫秒值格式化为999，mysql数据库时间毫秒值会四舍五入 自动加一秒，所以需要减去1秒
        DateTime dateTime = DateUtil.endOfDay(checkInTime);
        return DateUtil.offset(dateTime, DateField.SECOND, -1);
    }

    @Override
    public int offlinePayment(ProprietorBill proprietorBill) {
        String proprietorBillId = proprietorBill.getProprietorBillId();
        ProprietorBill proprietorBill1 = proprietorBillMapper.selectProprietorBillByProprietorBillId(proprietorBillId);
        String payVoucher = proprietorBill.getPayVoucher();
        if (StrUtil.isEmpty(payVoucher)) {
            throw new ServiceException("请上传图片");
        }

        if (!BillStateEnum.BILL_STATE_UNPAID.getValue().equals(proprietorBill1.getPayState()) &&
                !BillStateEnum.BILL_STATE_OVERDUE.getValue().equals(proprietorBill1.getPayState())) {
            throw new ServiceException("账单状态异常，请刷新后再试");
        }
        proprietorBill1.setPayVoucher(payVoucher);
        proprietorBill1.setPayTime(DateUtils.getNowDate());
        proprietorBill1.setPayState(BillStateEnum.BILL_STATE_PAID.getValue());
        proprietorBill1.setPayMethod(BillStateEnum.BILL_METHOD_OFFLINE.getValue());
        proprietorBill1.setUpdateTime(DateUtils.getNowDate());
        return proprietorBillMapper.updateProprietorBill(proprietorBill1);
    }

    @Override
    public void proprietorBillOvertimeTask() {
        Date nowDate = DateUtils.getNowDate();
        List<ProprietorBill> proprietorBills = selectProprietorBillList(ProprietorBill.builder().payState(BillStateEnum.BILL_STATE_UNPAID.getValue()).build());
        if (CollectionUtil.isNotEmpty(proprietorBills)) {
            for (ProprietorBill proprietorBill : proprietorBills) {
                if (DateUtil.compare(proprietorBill.getLatestPayTime(), nowDate) <= 0) {
                    proprietorBill.setPayState(BillStateEnum.BILL_STATE_OVERDUE.getValue());
                    proprietorBill.setUpdateTime(DateUtils.getNowDate());
                }
            }
            updateProprietorBillBatch(proprietorBills);
        }
        log.info("业主账单逾期定时任务执行完成");
    }

    @Override
    public void updateProprietorBillBatch(List<ProprietorBill> proprietorBills) {
        proprietorBillMapper.updateProprietorBillBatch(proprietorBills);
    }

    @Override
    public void payCallbackBill(ParseParam parseParam) {

        String outTradeNo = parseParam.getOutTradeNo();
        String billId = StrUtil.split(outTradeNo, "_")[0];

        // 删除redis的key，防止触发缓存过期回调时间
        redisCache.deleteObject(BillConstants.REDIS_PROPRIETOR_BILL_KEY + billId);
        ProprietorBill proprietorBill = selectProprietorBillByProprietorBillId(billId);
        if (ObjectUtil.isEmpty(proprietorBill)) {
            log.error("查询不到账单,参数：{}", JSONObject.toJSONString(parseParam));
            return;
        }
        // 保存微信支付回到参数
        WechatPayRecord wechatPayRecord = new WechatPayRecord();
        BeanUtil.copyProperties(parseParam, wechatPayRecord);
        wechatPayRecordService.insertWechatPayRecord(wechatPayRecord);

        // 修改账单状态
        proprietorBill.setPayTime(wechatPayRecord.getTimeEnd());
        proprietorBill.setPayState(BillStateEnum.BILL_STATE_PAID.getValue());
        proprietorBill.setPayMethod(BillStateEnum.BILL_METHOD_ONLINE.getValue());

        proprietorBill.setUpdateTime(DateUtils.getNowDate());
        proprietorBillMapper.updateProprietorBill(proprietorBill);
    }

    @Override
    public List<ProprietorBill> selectProprietorBillByHouseIds(String[] houseIds) {
        return proprietorBillMapper.selectProprietorBillByHouseIds(houseIds);

    }

}
